<?php
/**
 * Created by PhpStorm.
 * User: YongXuan.Huang
 * Date: 2017/10/1
 * Time: 20:36
 */


namespace Common\Common;

use Admin\Model\WebSetting;
use Exception;

class FileSystem
{
    /**
     * File
     *
     * @var array
     */
    private $file;

    /**
     * 过滤文件
     *
     * @var array = [];
     */
    private $filter;

    /**
     * 图片保存路径
     *
     * @var string
     */
    private $path = '';

    /**
     * 限制上传文件
     */
    const FILTER_MIME = 1;

    /**
     * 限制上传文件大小
     */
    const FILTER_MAX_SIZE = 2;

    public function __construct($file)
    {
        $this->file = $file;
    }

    /**
     * 保存文件
     *
     * @param bool $antiFake
     * @return string 文静储存的路径
     */
    public function saveFile($antiFake = true)
    {
        try {
            $this->checkFile();
            $path = '.\\' . $this->path . DIRECTORY_SEPARATOR . 'upload';
            Catalogue::makeDirectory($path);
            $fileName = md5_file($this->file['tmp_name']);
            $extension = $this->getFileExtension();
            $filePath = $path . DIRECTORY_SEPARATOR . $fileName . '.' . $extension;
            move_uploaded_file($this->file['tmp_name'], $filePath);
            $filePath = str_replace('\\', '/', ltrim($filePath, '.'));
            if ($antiFake) $this->addAntiFake('.' . $filePath);
            return $filePath;
        } catch (Exception $e) {
            echo null;
        }
        return false;
    }

    private function getFileExtension()
    {
        return substr($this->file['name'], strrpos($this->file['name'], '.') + 1);
    }

    /**
     * @return bool
     * @throws Exception
     */
    private function checkFile()
    {
        $this->getError();
        if (isset($this->filter)) {
            if (isset($this->filter[self::FILTER_MIME])) {
                if (!in_array($this->file['type'], $this->filter[self::FILTER_MIME])) {
                    throw new Exception('文件类型不匹配');
                }
            }
            if (isset($this->filter[self::FILTER_MAX_SIZE])) {
                if ($this->file['size'] > $this->filter[self::FILTER_MAX_SIZE]) {
                    throw new Exception('文件大小超出限制');
                }
            }
        }
        return true;
    }

    /**
     * 检测文件是否有错误
     *
     * @return bool
     * @throws Exception
     */
    private function getError()
    {
        $arr = ['code' => $this->file['error']];
        switch ($this->file['error']) {
            case 0:
                break;
            case 1:
                $arr['data'] = '上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。';
                break;
            case 2:
                $arr['data'] = ('上传文件大小超出了HTML表单隐藏域属性的MAX＿FILE＿SIZE元素所指定的最大值。');
                break;
            case 3:
                $arr['data'] = ('文件只被部分上传。');
                break;
            case 4:
                $arr['data'] = ('没有上传任何文件。');
                break;
            case 6:
                $arr['data'] = ('找不到临时文件夹');
                break;
            case 7:
                $arr['data'] = ('文件写入失败');
                break;
            default:
                break;
        }
        if ($arr['code'] > 0) {
            throw new Exception($arr['data'], $arr['code']);
        }
        return true;
    }

    /**
     * @param array $filter
     */
    public function setFilter(array $filter)
    {
        $this->filter = $filter;
    }

    /**
     * @param string $path
     */
    public function setPath($path)
    {
        $this->path = trim($path, '/\\');
    }

    public static function uploadFile($name)
    {
        $file = new static($_FILES[$name]);
        $file->setPath('Public');
        return $file->saveFile(true);
    }

    public static function uploadFile2NoAntiFake($name)
    {
        $file = new static($_FILES[$name]);
        $file->setPath('Public');
        return $file->saveFile(false);
    }

    /**
     * 添加水印
     *
     * @param $path
     * @return null
     */
    public function addAntiFake($path)
    {
        $img = WebSetting::findByKey(WebSetting::KEY_ANTI_FAKE_IMAGE);
        $text = WebSetting::findByKey(WebSetting::KEY_ANTI_FAKE_TEXT);
        $info = getimagesize($path);
        if ($info === false) {
            return null;
        }
        $image = $this->getImageResource($info['mime'], $path);
        if (!empty($text) && $text['is_enable'] == 1) {
            imagestring(
                $image,
                5,
                10,
                $info[1] - 20,
                $text['value'],
                imagecolorallocate($image, 0, 0, 0)
            );
        }
        if (!empty($img) && $img['is_enable'] == 1) {
            $loginFilePath = '.' . $img['value'];
            $logoImgInfo = getimagesize($loginFilePath);
            $logo = $this->getImageResource($logoImgInfo['mime'], $loginFilePath);
            imagealphablending($logo, 1);
            imagealphablending($image, 1);
            $x = $info[0] - $logoImgInfo[0] > 0 ? $info[0] - $logoImgInfo[0] : 0;
            $y = $info[1] - $logoImgInfo[1] > 0 ? $info[1] - $logoImgInfo[1] : 0;
            imagecopy($image, $logo, $x,$y,0,0,$logoImgInfo[0],$logoImgInfo[1]);
            imagedestroy($logo);
        }
        imagejpeg($image, $path);
        imagedestroy($image);
    }

    /**
     * 根据mine创建画布
     *
     * @param $mime
     * @param $path
     * @return null|resource
     */
    public function getImageResource($mime, $path)
    {
        $explode = explode('/', $mime, 2);
        if (sizeof($explode) != 2) {
            return null;
        }

        $method = 'imageCreateFrom' . $explode[1];

        if (function_exists($method)) {
            return $method($path);
        }
        return null;
    }
}